#coding:utf8
from decimal import Decimal

from django_redis import get_redis_connection
from rest_framework import serializers

from goods.models import SKU


class CartSKUSerializer(serializers.ModelSerializer):
    """
    购物车商品数据序列化器
    """
    count = serializers.IntegerField(label='数量')

    class Meta:
        model = SKU
        fields = ('id', 'name', 'default_image_url', 'price', 'count')


class PlaceOrderSerialzier(serializers.Serializer):

    skus = CartSKUSerializer(many=True)
    freight = serializers.DecimalField(max_digits=10,decimal_places=2)

from orders.models import OrderInfo, OrderGoods


class OrderCommitSerializer(serializers.ModelSerializer):
    class Meta:
        model = OrderInfo
        fields = ('order_id', 'address', 'pay_method')
        read_only_fields = ('order_id',)
        extra_kwargs = {
            'address': {
                'write_only': True,
                'required': True,
            },
            'pay_method': {
                'write_only': True,
                'required': True
            }
        }



    def create(self, validated_data):
        """
         #1. 先获取user,address
        #2.自己生成一个订单id
        #3.初始化订单价格，订单数量，订单运费
        #4.支付状态和订单状态
        #5.订单就生成了


        #6.（必须先有订单号才能有订单商品）生成订单商品
        #连接redis
        #7.hash
        #8.set
        #9.组织选中商品的信息
        # 【SKU,SKU,SKU】

        #10对选中的商品，进行遍历
        # 11.判断库存是否充足
        # 12订单已经生成了，销量和库存就应该对应的变化
        # 13.订单信息的累加操作
        # 14. 商品信息入库


        """

        #1. 先获取user,address
        user = self.context['request'].user

        address = validated_data.get('address')
        #2.自己生成一个订单id
        # order_id --> YmdHMS+固定位数的个人id信息
        from django.utils import timezone
        # f 微秒
        order_id = timezone.now().strftime('%Y%m%d%H%M%S%f') + ('%08d'%user.id)

        #3.初始化订单价格，订单数量，订单运费
        total_count = 0
        total_amount = Decimal('0')
        freight = Decimal('10.00')

        #4.支付状态和订单状态
        pay_method = validated_data.get('pay_method')

        #
        # if pay_method == 1:
        #     status = 2
        #     pass
        # else:
        #       status = 1
        #     pass



        if pay_method == OrderInfo.PAY_METHODS_ENUM['CASH']:
            status = OrderInfo.ORDER_STATUS_ENUM['UNSEND']
        else:
            status = OrderInfo.ORDER_STATUS_ENUM['UNPAID']

        #  添加事物
        from django.db import transaction

        with transaction.atomic():
            #部分代码使用事务

            # 创建一个保存点
            save_id = transaction.savepoint()
            try:
                #5.订单就生成了
                order = OrderInfo.objects.create(
                    order_id=order_id,
                    user=user,
                    address=address,
                    total_amount=total_amount,
                    total_count=total_count,
                    freight=freight,
                    pay_method=pay_method,
                    status=status
                )






                #6.（必须先有订单号才能有订单商品）生成订单商品
                #连接redis
                redis_conn = get_redis_connection('cart')
                #7.hash
                redis_id_count = redis_conn.hgetall('cart_%s'%user.id)
                #8.set
                redis_selected_ids = redis_conn.smembers('cart_selected_%s'%user.id)

                redis_data = {}

                for sku_id in redis_selected_ids:
                    redis_data[int(sku_id)] = int(redis_id_count[sku_id])
                #9.组织选中商品的信息
                # redis_data = {sku_id:count}

                # 【SKU,SKU,SKU】
                skus = SKU.objects.filter(pk__in=redis_data.keys())




                #10对选中的商品，进行遍历
                for sku in skus:
                    # 11.判断库存是否充足
                    count = redis_data[sku.id]
                    if count > sku.stock:
                        transaction.savepoint_rollback(save_id)
                        raise serializers.ValidationError('库存不足')
                    # 12订单已经生成了，销量和库存就应该对应的变化

                    import time
                    # time.sleep(10)

                    # sku.stock -= count
                    # sku.sales += count
                    # sku.save()

                    # 先记录库存
                    old_stock = sku.stock           #15

                    #计算要更新的值
                    new_stock = sku.stock - count
                    new_sales = sku.sales + count

                    # 再更新的时候，先查询库存是否和之前的一致，如果一致则更新
                    # 如果不一致则不更新
                    rect = SKU.objects.filter(pk=sku.id,stock=old_stock).update(stock=new_stock,sales=new_sales)

                    #当返回值为0的时候，表示下单失败
                    if rect == 0:
                        transaction.savepoint_rollback(save_id)
                        raise serializers.ValidationError('下单失败')


                    # 13.订单信息的累加操作
                    order.total_count += count
                    order.total_amount += (sku.price*count)
                    # 14. 商品信息入库
                    OrderGoods.objects.create(
                        order=order,
                        sku=sku,
                        count=count,
                        price=sku.price
                    )

                #保存累加信息
                order.save()
            except Exception as e:
                transaction.savepoint_rollback(save_id)
                raise serializers.ValidationError('下单失败')
            else:
                transaction.savepoint_commit(save_id)

        return order
